// ==========================================================================
//										
//	- Calculatrice (Header)	
//
// ==========================================================================

/*!
*
*	\file calculatrice.h
*	\brief Ce fichier contiendra la classe Calculatrice.\n\n
*			C'est ici que seront traitees les fonctions de la calculatrice :\n
*			Menu, Saisie d'une expression, Analyse de l'expression, Calcul de l'expression, Sauvegarde dans un fichier, Chargement depuis un fichier.
*	\author M.BOAZIZ R.BOUAYADI C.DRAMSY A.OCCELLO D.SENG
*	\version 0.1
*	\date 11 mai 2010	
*
*/

#ifndef H_CALCULATRICE
#define H_CALCULATRICE

#include <iostream>
#include <string.h>
#include <limits>
#include <vector>
#include "netg.h"
#include "element.h"
#include "opeadd.h"
#include "opemul.h"

/*!
*
*	\brief Class Calculatrice
*/
class Calculatrice
{
	protected:
		std::string Exp;
		std::vector<Element> Elements;
		
	public:
		// Constructeurs
		/*!
		*
		*	\brief Constructeur de la classe Calculatrice
		*/	
		Calculatrice();
		// Destructeurs
		/*!
		*
		*	\brief Destructeur de la classe Calculatrice
		*/		
		virtual ~Calculatrice();
		
		
		// Methodes
		/*!
		*
		* \brief Menu de la calculatrice permettant d'entrer une expression contenant
		*	des tres grands nombres et d'effectuer des operations.\n Le menu
		*	sera presente comme un index 1) Option.
		*/
		void menu();
		/*!
		*
		* \brief Fonction de saisie.
		*	La chaine de caractere saisie doit etre correcte.\n
		*	Sinon genere une erreur a l'utilisateur l'informant que la saisie est
		*	incorrecte sinon stocke l'expression saisie dans Exp.\n
		*	La saisie doit etre de la forme :
		*	- Elle doit commencer par un nombre\n
		*	- Peut-etre suivit par toute suite d'operateurs suivit d'un nombre\n
		*	- Peut contenir des espaces entre les nombres et les operateurs\n
		*	- Ne peut contenir des caracteres speciaux ou des lettres en dehors des
		*	operateurs et de l'exposant utilisant le caractere 'e'
		*/
		void saisie();
		/*!
		*
		* \brief Analyse les donnees de l'expression saisie et stockee dans Exp.
		*	Decoupe la chaine de caractere, les identifies en fonction de leur forme
		*	et cree les elements correspondants pour le stocker dans le vector
		*	d'elements.
		*
		*	On procedera a plusieurs analyses.
		*	
		*	Une analyse primaire ou :
		*	On inserera dans le tableau Elements dans l'ordre dans lequel
		*	ils apparaissent :
		*	- tout nombre creera un NETG le contenant, chaque chiffre du NETG
		*	sera insere successivement
		*	- tout caractere + ou - creera un Operateur addition contenant le
		*	char
		*	- tout caractere * ou / creera un Operateur multiplication contenant
		*	le char
		*	- si une parenthese est identifiee, tout ce qui suit sera contenu
		*	dans une Expression creee jusqu'a detecter une parenthese fermante
		*	Dans le cas ou aucune parenthese fermante n'est detectee, l'expression
		*	sera jugee invalide et informee a l'utilisateur.
		*	
		*	On fera ensuite appel a la fonction analyser(int Type) pour chacuns des
		*	types : FACTEUR, TERME, EXPRESSION
		*/
		void analyser();
		/*!
		*
		* \brief Analyse des elements contenu dans Elements.
		*	
		*	Analyse des Facteurs :
		*		- Tout NETG est un Facteur
		*		- Tout Expression encapsulee par des parentheses est un Facteur
		*	
		*	Analyse des Termes :
		*		- Un Facteur est un Terme
		*		- Tout schema Facteur OpeMul Facteur sera contenu dans un meme
		*		Terme
		*		
		*	Analyse des Expressions :
		*		- Un Terme est une Expression
		*		- Tout schema Terme OpeAdd Terme sera contenu dans une meme
		*		Expression
		*/		
		void analyser(int Type);
		/*!
		*
		* \brief Fonction de calcul.
		*	L'expression a calculer doit etre stockee dans la chaine de caracteres
		*	Exp.
		*	Cette fonction appelle la fonction "void calcul(Element E)" pour chacuns
		*	des elements du vector d'elements.
		*	
		*	Calcul des Facteurs :
		*		- Un Facteur ne contenant qu'un NETG, la valeur d'un Facteur
		*		sera retournee par celle du NETG contenu
		*		- Un Facteur contenant une Expression, retournera la valeur
		*		du calcul de l'Expression.
		*	
		*	Calcul des Termes :
		*		- Si le Terme ne contient qu'un Facteur, renvoit le calcul du Facteur
		*		- Si le Terme contient plus d'un Facteur et au moins un OpeMul
		*		On simplifiera le contenu du Terme en multipliant les Facteurs,
		*		le produit de deux facteurs resultera a la creation d'un seul Facteur
		*		contenant le resultat du produit.
		*		- La multiplication de deux Facteurs contenus dans un Terme se fera tant
		*		qu'il existe un OpeMul jusqu'au final qu'il ne contienne qu'un seul
		*		Facteur existant dans le Terme.
		*		
		*	Calcul des Expressions :
		*		- Si l'Expression ne contient qu'un Terme, renvoit le calcul du Terme
		*		- Si l'Expression contient plus d'un Terme et au moins un OpeAdd
		*		On simplifiera le contenu de l'Expression en multipliant les Termes
		*		calcules, la somme de deux termes calcules resultera a la creation
		*		d'un seul Terme calcule contenant le resultat de la somme.
		*		- La somme de deux Termes calcules contenus dans une Expression
		*		se fera tant qu'il existe un OpeAdd jusqu'au final qu'il ne contienne
		*		qu'un seul Terme calcule existant dans le Terme.
		*/		
		void calcul();
		/*!
		*
		* \brief Fonction qui calcule l'element passe en parametre qui peut etre :
		*	- Expression.
		*	- Terme.
		*	- Facteur.
		*/		
		void calcul(Element E);
		/*!
		*
		* \brief Filename : nom du fichier ou sera sauvegarde le NETG
		*	
		*	Permet de sauvegarder un NETG dans un fichier.
		*	Le NETG sera retranscrit dans un fichier texte .netg.
		*	Le nom du fichier doit respecter les contraintes suivantes :
		*	- il ne doit pas commencer par un chiffre
		*	- il ne peut pas contenir de caracteres speciaux
		*	- le fichier doit exister et etre trouve a l'adresse indiquee par Filename
		*/		
		void sauvegarder(std::string Filename);
		/*!
		*
		* \brief Filename : nom du fichier ou est sauvegarde le NETG
		*	Ope : operateur qui va preceder le NETG charge peut etre - ou +
		*	
		*	Permet de charger NETG a partir d'un fichier. 
		*	Remplace le contenu du tableau dynamique par celui du fichier charge.
		*	Le nom du fichier doit respecter les meme contraintes que ceux de la
		*	sauvegarde + le nom du fichier doit porter l'extension associee .netg.
		*	
		*	Cette fonction permet de charger un netg et de le preceder d'un
		*	operateur - ou + dans l'expression courante. Il est necessaire
		*	d'avoir une seconde methode similaire pour gerer * et \.
		*/		
		void charger(std::string Filename, OpeAdd Ope);
		/*!
		*
		* \brief Filename : nom du fichier ou est sauvegarde le NETG
		*	Ope : operateur qui va preceder le NETG charge peut etre * ou \
		*	
		*	Idem pour * et \.
		*	Le NETG charge ne doit pas etre nul si l'operateur \ veut etre utilise.
		*/
		void charger(std::string Filename, OpeMul Ope);
};

#endif
